
package com.shop.loan.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 1、body请求体转表单请求
 * 2、解决body请求体重复读取
 * 3、内容防XSS攻击
 */
public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private Map<String, String[]> params = new HashMap<>();

    private final byte[] body;

    public ParameterRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);

        //将form请求添加到map中
        addAllParameters(request.getParameterMap());

        String bodyString = inputStream2String(request.getInputStream());
        if (JSON.isValidObject(bodyString)) {
            Map<String, String[]> map = JSONObject.parseObject(bodyString, Map.class);
            //将body请求添加到map中
            addAllParameters(map);
        }else{
            Map<String, String[]> map = new HashMap<>();
            map.put("sReqData",new String[]{bodyString});
            addAllParameters(map);
        }
        body = bodyString.getBytes(Charset.forName("UTF-8"));
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(params.keySet());
    }

    @Override
    public String getParameter(String name) {
        String[] values = params.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }

    public void addAllParameters(Map<String, String[]> otherParams) {
        if (otherParams == null) {
            return;
        }
        for (Map.Entry<String, String[]> entry : otherParams.entrySet()) {
            addParameter(entry.getKey(), entry.getValue());
        }
    }


//    public void addParameter(String name, Object value) {
//        if (value != null) {
//            if (value instanceof String[]) {
//                params.put(name, (String[]) value);
//            } else if (value instanceof String) {
//                params.put(name, new String[]{(String) value});
//            } else {
//                params.put(name, new String[]{String.valueOf(value)});
//            }
//        }
//    }

    public void addParameter(String name, Object value) {
        if (value != null) {
            if (value instanceof String[]) {
                String[] values = (String[]) value;
//                for (int i = 0; i < values.length; i ++){
//                    String escapeValue = StringUtils.replaceHtml(values[i]);
//                    values[i] = escapeValue;
//                }
                params.put(name, values);
            } else {
                String dataValue;
                if (value instanceof String) {
                    dataValue = (String) value;
                } else {
                    dataValue = String.valueOf(value);
                }
//                对参数内容安全检查
//                String escapeValue = StringUtils.replaceHtml(dataValue);
//                params.put(name, new String[]{escapeValue});

                params.put(name, new String[]{dataValue});
            }
        }
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return this.params;
    }


    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
        return new ServletInputStream() {

            @Override
            public int read() {
                return byteArrayInputStream.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }


    /**
     * 将inputStream里的数据读取出来并转换成字符串
     *
     * @param inputStream inputStream
     * @return String
     */
    private String inputStream2String(InputStream inputStream) {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
//            sb.append("body参数获取失败");
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

}
